﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

using MetaVideoEditorEvolved.Helper;

namespace mveEngine
{
	public class Kernel : INotifyPropertyChanged
	{
		static object sync = new object();
		static Kernel kernel;

		public static void Init()
		{
			ConfigData config = null;
			config = ConfigData.FromFile(ApplicationPaths.ConfigFile);
			Init(config);
		}
		
		public static event EventHandler SupportedVersionChanged;

		public static void Init(ConfigData config)
		{
			lock (sync)
			{
				var kernel = GetDefaultKernel(config);
				Kernel.Instance = kernel;
			}
			Tracer.TracerInstance.TraceInformation("kernel loaded");
		}

		static Kernel GetDefaultKernel(ConfigData config)
		{
			var kernel = new Kernel()
			{
				StringData = new LocalizedStrings(),
				ConfigData = config
			};
			kernel.ItemCollection = new ItemCollection(config.RootFolders);
			kernel.Message = new GenerateMessage();

			return kernel;
		}

		/// <summary>
		/// Read the cache version, stored with filename pattern x.x.x.x.cache, if no file found version 0 is returned
		/// </summary>
		/// <returns>The version of the cache</returns>
		public static Version DetectedCacheVersion()
		{
			var version = new Version();

			if (!Directory.Exists(ApplicationPaths.AppCachePath))
			{
				return version;
			}

			var files = Directory.GetFiles(ApplicationPaths.AppCachePath, "*.cache");

			if (!files.Any())
			{
				return version;
			}

			var versions = from cacheVersion in files
				select new Version(Path.GetFileName(cacheVersion).Replace(".cache", string.Empty));

			var lastVersion = (from ver in versions
			                   orderby version descending
			                   select ver).First();

			return lastVersion;
		}

		/// <summary>
		/// Return the supported cache version, if detected cache version is not the same it is necessary to delete the cache
		/// </summary>
		/// <returns>The version</returns>
		public static Version SupportedCacheVersion()
		{
			return new Version(2, 0);
		}

		/// <summary>
		/// Update the cache version with the supported version
		/// </summary>
		public static void SetSupportedVersionInCache()
		{
			if (!Directory.Exists(ApplicationPaths.AppCachePath))
			{
				Directory.CreateDirectory(ApplicationPaths.AppCachePath);
			}

			var filePath = Path.Combine(ApplicationPaths.AppCachePath, Kernel.SupportedCacheVersion().ToString() + ".cache");
			File.Create(filePath);
			
			if (SupportedVersionChanged!=null) {
				SupportedVersionChanged(null, null);
			}
		}

		public LocalizedStrings StringData { get; set; }
		public ConfigData ConfigData { get; set; }
		
		private ItemCollection itemCollection;
		public ItemCollection ItemCollection
		{
			get	
			{
				return this.itemCollection;
			}
			
			set
			{
				this.itemCollection = value;				
				this.OnNotifyPropertyChanged("ItemCollection");
			}
		}
		public GenerateMessage Message;

		public static void ReloadKernel()
		{
			kernel = null;
			Init();
		}

		public static Kernel Instance
		{
			get
			{
				if (kernel != null) return kernel;
				lock (sync)
				{
					if (kernel != null) return kernel;
					Init();
				}
				return kernel;
			}
			set
			{
				lock (sync)
				{
					kernel = value;
				}
			}
		}

		public string GetString(string name)
		{
			return this.StringData.GetString(name);
		}
	
		protected void OnNotifyPropertyChanged(string propertyName)
		{
			if (this.PropertyChanged!=null) {
				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}
		
		public event PropertyChangedEventHandler PropertyChanged;
	}
}